package cn.anzhiyublog.staranimegallery.service.impl;

import cn.anzhiyublog.staranimegallery.cache.template.CaffeineCache;
import cn.anzhiyublog.staranimegallery.cache.template.RedisCache;
import cn.anzhiyublog.staranimegallery.exception.GalleryException;
import cn.anzhiyublog.staranimegallery.mapper.PictureMapper;
import cn.anzhiyublog.staranimegallery.model.domain.Picture;
import cn.anzhiyublog.staranimegallery.model.domain.Space;
import cn.anzhiyublog.staranimegallery.model.domain.User;
import cn.anzhiyublog.staranimegallery.model.dto.picture.*;
import cn.anzhiyublog.staranimegallery.model.enums.Authority;
import cn.anzhiyublog.staranimegallery.model.enums.ReviewStatus;
import cn.anzhiyublog.staranimegallery.model.enums.Role;
import cn.anzhiyublog.staranimegallery.model.enums.StatusCode;
import cn.anzhiyublog.staranimegallery.model.vo.PictureVO;
import cn.anzhiyublog.staranimegallery.service.PictureService;
import cn.anzhiyublog.staranimegallery.service.SpaceService;
import cn.anzhiyublog.staranimegallery.util.*;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 空间图片层
 *
 * @author 安知一只鱼
 */
@Service
@Slf4j
public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture> implements PictureService {
    @Autowired
    private SpaceService spaceService;
    @Autowired
    private COSUtils cosUtils;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private JsoupUtils jsoupUtils;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private CaffeineCache caffeineCache;

    @Override
    public Picture uploadPictureByFile(MultipartFile pictureFile, PictureUploadRequest pictureUploadRequest,
                                       User loginUser) {
        Long pictureId = pictureUploadRequest.getPictureId();
        Long spaceId = pictureUploadRequest.getSpaceId();
        // 填了空间id为私人图库
        if (spaceId!=null){
            // 校验空间存在(如果没有会在别的地方抛异常)
            Space space = spaceService.getSpaceById(spaceId);
            // 校验是否为本人
            ThrowUtils.throwIf(!space.getUserId().equals(loginUser.getId()), StatusCode.FORBIDDEN, "空间不存在或无权限");
            // 额度校验
            ThrowUtils.throwIf(space.getCurrentCount()>=space.getMaxCount(), StatusCode.CONFLICT, "空间图片数量已达上限");
            ThrowUtils.throwIf(space.getCurrentCapacity()>=space.getMaxCapacity(), StatusCode.CONFLICT, "空间容量已达上限");
        }
        // 根据id判断此次上传是更新图片还是新增图片
        if (pictureId!=null){
            // 图片存在校验(没有会在其他方法抛异常)
            Picture picture = this.getPictureById(pictureId,loginUser);
            // 空间一致校验（如果有就复用）
            if (spaceId != null){
                // 空间一致校验
                ThrowUtils.throwIf(!picture.getSpaceId().equals(spaceId), StatusCode.CONFLICT, "空间不一致");
            }else {
                if (picture.getSpaceId()!=null){
                    spaceId = picture.getSpaceId();
                }
            }
            // 更新图片则要删除老图片
            cosUtils.deletePictureByObject(picture);
        }
        // 准备上传：根据用户id划分目录、执行上传、构建入库数据、管理员上传的自动审核、如果是更新图片还需修改编辑时间
        String uploadPath = String.format("ZhiyuStarAnimeGallery/public/%s", loginUser.getId());
        PictureUploadResult pictureUploadResult = cosUtils.uploadPictureByFile(uploadPath, pictureFile);
        Picture picture = buildPicture(pictureUploadResult, loginUser, spaceId);
        // 删除对象存储中的原图
        cosUtils.deleteOriginalPicture(picture);
        // 事务执行上传操作、保持额度更新
        Long finalSpaceId = spaceId;
        transactionTemplate.execute(status -> {
            boolean isOK = this.saveOrUpdate(picture);
            ThrowUtils.throwIf(!isOK, StatusCode.INTERNAL_SERVER_ERROR, "图片上传失败");
            // 如果是上传到空间则要清算额度
            if (finalSpaceId !=null){
                boolean isUpdate = spaceService.lambdaUpdate()
                        .eq(Space::getId, finalSpaceId)
                        .setSql("current_capacity = current_capacity + " + picture.getPictureSize())
                        .setSql("current_count = current_count + 1")
                        .update();
                // 回滚
                ThrowUtils.throwIf(!isUpdate, StatusCode.INTERNAL_SERVER_ERROR, "空间额度更新失败");
            }
            return picture;
        });
        return picture;
    }

    @Override
    public Picture uploadPictureByUrl(PictureUrlUploadRequest pictureUrlUploadRequest, User loginUser) {
        // 获取url
        String url = pictureUrlUploadRequest.getUrl();
        // 校验数据库图片
        if (pictureUrlUploadRequest.getPictureId() != null){
            Picture picture = this.getPictureById(pictureUrlUploadRequest.getPictureId(), loginUser);
            // 更新图片则要删除老图片
            cosUtils.deletePictureByObject(picture);
        }
        if (pictureUrlUploadRequest.getSpaceId() != null){
            // 校验空间是否存在
            Space space = spaceService.getById(pictureUrlUploadRequest.getSpaceId());
            ThrowUtils.throwIf(space==null,  StatusCode.NOT_FOUND, "空间不存在");
            // 校验是否为本人
            ThrowUtils.throwIf(!loginUser.getId().equals(space.getUserId()),StatusCode.FORBIDDEN);
        }
        // 根据用户id划分目录
        String uploadPathPrefix = String.format("ZhiyuStarAnimeGallery/public/%s", loginUser.getId());
        // 执行上传
        PictureUploadResult pictureUploadResult = cosUtils.uploadPictureByUrl(uploadPathPrefix,url);
        // 构造上传信息（包括自动审核）
        Picture picture = buildPicture(pictureUploadResult, loginUser, pictureUrlUploadRequest.getSpaceId());
        // 删除对象存储中的原图
        cosUtils.deleteOriginalPicture(picture);
        // 事务执行上传操作、保持额度更新
        Long finalSpaceId = pictureUrlUploadRequest.getSpaceId();
        transactionTemplate.execute(status -> {
            boolean isOK = this.saveOrUpdate(picture);
            ThrowUtils.throwIf(!isOK, StatusCode.INTERNAL_SERVER_ERROR, "图片上传失败");
            // 如果是上传到空间则要清算额度
            if (finalSpaceId !=null){
                boolean isUpdate = spaceService.lambdaUpdate()
                        .eq(Space::getId, finalSpaceId)
                        .setSql("current_capacity = current_capacity + " + picture.getPictureSize())
                        .setSql("current_count = current_count + 1")
                        .update();
                // 回滚
                ThrowUtils.throwIf(!isUpdate, StatusCode.INTERNAL_SERVER_ERROR, "空间额度更新失败");
            }
            return picture;
        });
        return picture;
    }

    @Override
    public PictureSpiderUploadResult uploadPictureBySpider(PictureSpiderUploadRequest pictureSpiderUploadRequest, User loginUser) {
        // Jsoup发送请求获取图片的元素列表
        Document page = jsoupUtils.getPage(pictureSpiderUploadRequest);
        Elements images = jsoupUtils.getImages(page);
        // 批量获取url并执行上传
        int current = 0; // 当前个数
        int total = pictureSpiderUploadRequest.getSize(); // 最大个数
        int success = 0; // 成功个数
        List<Picture> pictures = new ArrayList<>();
        for (Element image: images){
            current++;
            // 获取url
            String url = image.attr("src");
            if (StrUtil.isBlank(url)){
                // 链接为空，跳过
                log.info("第{}次：上传失败，未发现url",current);
                continue;
            }
            // 删除问号后的所有的字符串（如果存在）
            int mark = url.indexOf("?");
            if (mark>1){
                url = url.substring(0,mark);
            }
            // 执行上传
            PictureUrlUploadRequest pictureUrlUploadRequest = new PictureUrlUploadRequest();
            pictureUrlUploadRequest.setUrl(url);
            try{
                Picture picture = this.uploadPictureByUrl(pictureUrlUploadRequest, loginUser);
                pictures.add(picture);
                log.info("第{}次：上传成功",current);
                success++;
            }catch (Exception e){
                log.info("第{}次：上传失败，{}",current,e.getMessage());
            }
            if (current>=total){
                // 如果达到了上传要求，之间终止循环
                break;
            }
        }
        // 构造结果
        PictureSpiderUploadResult result = new PictureSpiderUploadResult();
        result.setTotal(total);
        result.setSuccess(success);
        result.setPictures(this.ObjToVO(pictures));
        return result;
    }

    @Override
    public void deletePicture(PictureDeleteRequest pictureDeleteRequest, User loginUser) {
        Long pictureId = pictureDeleteRequest.getId();
        // 判断图片是否存在(没有会在其他地方抛异常)
        Picture picture = this.getPictureById(pictureId,loginUser);
        // 检查图片有无空间id
        if (picture.getSpaceId()==null){
            // 如果是公共图库的，判断账号是否为管理员或者本人
            boolean isHasPermission = Authority.inManage(Role.getEnumByCode(loginUser.getRole())) || loginUser.getId().equals(picture.getUserId());
            ThrowUtils.throwIf(!isHasPermission, StatusCode.FORBIDDEN);
        } else {
            // 如果是私有图库的，判断是不是本人
            ThrowUtils.throwIf(!loginUser.getId().equals(picture.getUserId()), StatusCode.FORBIDDEN);
        }
        // 使用事务进行删除操作
        transactionTemplate.execute(status -> {
            boolean isDelete = this.removeById(pictureId);
            ThrowUtils.throwIf(!isDelete, StatusCode.INTERNAL_SERVER_ERROR, "删除失败");
            // 如果是私有图片还需要释放额度
            if (picture.getSpaceId()!=null){
                boolean isUpdate = spaceService.lambdaUpdate()
                        .eq(Space::getId, picture.getSpaceId())
                        .setSql("current_capacity = current_capacity - " + picture.getPictureSize())
                        .setSql("current_count = current_count-1")
                        .update();
                ThrowUtils.throwIf(!isUpdate, StatusCode.INTERNAL_SERVER_ERROR, "额度更新失败");
            }
            // 删除对象存储中的图片
            cosUtils.deletePictureByObject(picture);
            return true;
        });
    }

    @Override
    public void updatePicture(PictureUpdateRequest pictureUpdateRequest, User loginUser) {
        // 请求转换实体
        Picture picture = new Picture();
        BeanUtil.copyProperties(pictureUpdateRequest, picture);
        picture.setTags(JSONUtil.toJsonStr(pictureUpdateRequest.getTags()));
        // 数据校验
        this.validPicture(picture);
        // 存在校验
        Picture p = this.getById(picture.getId());
        // 本人或管理员校验
        if (p.getSpaceId()==null){
            // 如果没有空间id就是公共图库的
            boolean isOk = p.getUserId().equals(loginUser.getId()) || Authority.inManage(Role.getEnumByCode(loginUser.getRole()));
            ThrowUtils.throwIf(!isOk,StatusCode.FORBIDDEN);
        }else {
            // 校验空间是否存在
            Space space = spaceService.getById(p.getSpaceId());
            ThrowUtils.throwIf(space==null, StatusCode.NOT_FOUND, "空间不存在");
            // 如果是私人图库的，需要校验是否为本人操作，就算是管理员也不行
            ThrowUtils.throwIf(!loginUser.getId().equals(space.getUserId()), StatusCode.FORBIDDEN);
        }
        // 修改审核状态
        picture.setReviewerId(p.getReviewerId());
        picture.setReviewTime(p.getReviewTime());
        fillReviewInfo(picture, loginUser);
        // 修改数据
        boolean isUpdate = this.updateById(picture);
        ThrowUtils.throwIf(!isUpdate, StatusCode.INTERNAL_SERVER_ERROR, "修改失败");
    }

    @Override
    public Picture getPictureById(long pictureId, User loginUser) {
        Picture picture = this.getById(pictureId);
        ThrowUtils.throwIf(picture==null, StatusCode.NOT_FOUND, "图片不存在");
        if (picture.getSpaceId()!=null){
            ThrowUtils.throwIf(!loginUser.getId().equals(picture.getUserId()), StatusCode.FORBIDDEN);
        }
        return picture;
    }

    @Override
    public Page<Picture> listPictureByPage(PicturePageQueryRequest picturePageQueryRequest,
                                           User loginUser) {
        // current必须为正、size在0-30之间
        ThrowUtils.throwIf(!(picturePageQueryRequest.getCurrent()>=0 && picturePageQueryRequest.getSize()>0
                && picturePageQueryRequest.getSize()<=30), StatusCode.BAD_REQUEST, "参数错误");
        // 构造查询条件
        LambdaQueryWrapper<Picture> pictureLambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 图片id，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getId()), Picture::getId, picturePageQueryRequest.getId());
        // 图片名称，模糊查询
        pictureLambdaQueryWrapper.like(StrUtil.isNotBlank(picturePageQueryRequest.getName()), Picture::getName, picturePageQueryRequest.getName());
        // 简介，模糊查询
        pictureLambdaQueryWrapper.like(StrUtil.isNotBlank(picturePageQueryRequest.getIntroduction()), Picture::getIntroduction, picturePageQueryRequest.getIntroduction());
        // 分类，模糊查询
        pictureLambdaQueryWrapper.like(StrUtil.isNotBlank(picturePageQueryRequest.getCategory()), Picture::getCategory, picturePageQueryRequest.getCategory());
        // 标签，循环、模糊查询
        if (CollUtil.isNotEmpty(picturePageQueryRequest.getTags())){
            for (String tag: picturePageQueryRequest.getTags()){
                pictureLambdaQueryWrapper.like(Picture::getTags,"\""+tag+"\"");
            }
        }
        // 大小，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getPictureSize()), Picture::getPictureSize, picturePageQueryRequest.getPictureSize());
        // 宽度，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getPictureWidth()), Picture::getPictureWidth, picturePageQueryRequest.getPictureWidth());
        // 高度，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getPictureHeight()), Picture::getPictureHeight, picturePageQueryRequest.getPictureHeight());
        // 比例，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getPictureScale()), Picture::getPictureScale, picturePageQueryRequest.getPictureScale());
        // 格式，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getPictureFormat()), Picture::getPictureFormat, picturePageQueryRequest.getPictureFormat());
        // 用户id，精准查询
        pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getUserId()), Picture::getUserId, picturePageQueryRequest.getUserId());
        // 开始时间，时间范围搜索
        pictureLambdaQueryWrapper.ge(ObjectUtil.isNotNull(picturePageQueryRequest.getStartDate()), Picture::getEditTime, picturePageQueryRequest.getStartDate());
        // 开始时间，时间范围搜索
        pictureLambdaQueryWrapper.le(ObjectUtil.isNotNull(picturePageQueryRequest.getEndData()), Picture::getEditTime, picturePageQueryRequest.getEndData());
        // 关键字,多字段查询 id、名称、简介、分类、标签、用户id
        if (StrUtil.isNotBlank(picturePageQueryRequest.getKeywords())){
            String keywords = picturePageQueryRequest.getKeywords();
            pictureLambdaQueryWrapper.and(
                    qw -> qw.eq(Picture::getId, keywords).or()
                            .like(Picture::getName, keywords).or()
                            .like(Picture::getIntroduction,keywords).or()
                            .like(Picture::getCategory, keywords).or()
                            .like(Picture::getTags, keywords).or()
                            .eq(Picture::getUserId, keywords)
            );
        }
        if (picturePageQueryRequest.getIsPublic()){
            if (picturePageQueryRequest.getReviewStatus()==null&&picturePageQueryRequest.getReviewerId()==null&&picturePageQueryRequest.getReviewMessage()==null){
                // 公共图的查询，公共图片要求过审、无空间
                pictureLambdaQueryWrapper.eq(Picture::getReviewStatus, ReviewStatus.PASSED.getCode());
                pictureLambdaQueryWrapper.isNull(Picture::getSpaceId);
            }else {
                // 公共图库未过审核查询（管理员）
                ThrowUtils.throwIf(!Authority.inManage(Role.getEnumByCode(loginUser.getRole())), StatusCode.FORBIDDEN);
                // 审核状态，精准查询
                pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getReviewStatus()), Picture::getReviewStatus, picturePageQueryRequest.getReviewStatus());
                // 审核人精准查询
                pictureLambdaQueryWrapper.eq(ObjectUtil.isNotNull(picturePageQueryRequest.getReviewerId()), Picture::getReviewerId, picturePageQueryRequest.getReviewerId());
            }
        }else {
            // 检查参数有无空间id
            ThrowUtils.throwIf(picturePageQueryRequest.getSpaceId()==null, StatusCode.BAD_REQUEST, "参数有误，您未输入空间id");
            // 图库必须存在
            Space space = spaceService.getSpaceById(picturePageQueryRequest.getSpaceId());
            // 查询私人图库必须是本人
            ThrowUtils.throwIf(!space.getUserId().equals(loginUser.getId()), StatusCode.FORBIDDEN);
            // 插入条件
            pictureLambdaQueryWrapper.eq(Picture::getSpaceId, picturePageQueryRequest.getSpaceId());
        }
        // 排序：目前只允许最后修改时间
        switch (picturePageQueryRequest.getSortOrder()){
            case "descend":
                pictureLambdaQueryWrapper.orderByDesc(Picture::getEditTime);
                break;
            case "ascend":
                pictureLambdaQueryWrapper.orderByAsc(Picture::getEditTime);
                break;
            default:
                System.out.println(picturePageQueryRequest.getSortOrder());
                throw new GalleryException(StatusCode.BAD_REQUEST, "排序方式有误");
        }
        // 执行分页查询
        return this.page(new Page<>(picturePageQueryRequest.getCurrent(), picturePageQueryRequest.getSize()), pictureLambdaQueryWrapper);
    }

    @Override
    public Page<Picture> listPictureByPageWithCache(PicturePageQueryRequest picturePageQueryRequest,
                                                    User loginUser) {
        Page<Picture> pictures;
        // 从caffeine本地缓存查询
        pictures = caffeineCache.getPictureQueryResult(picturePageQueryRequest);
        if (pictures!=null){
            return pictures;
        }
        // 从redis缓存查询
        pictures = redisCache.getPictureQueryResult(picturePageQueryRequest);
        if (pictures!=null){
            // 存入本地缓存
            caffeineCache.setPictureQueryResult(picturePageQueryRequest,pictures);
            return pictures;
        }
        // 从数据库查询
        pictures = this.listPictureByPage(picturePageQueryRequest, loginUser);
        // 存入缓存
        caffeineCache.setPictureQueryResult(picturePageQueryRequest,pictures);
        redisCache.setPictureQueryResult(picturePageQueryRequest,pictures);
        return pictures;
    }

    @Override
    public void reviewPicture(PictureReviewRequest pictureReviewRequest, User loginUser) {
        // 检查审核人权限
        ThrowUtils.throwIf(!Authority.inManage(loginUser),StatusCode.FORBIDDEN);
        // 检查审核状态
        Picture p = this.getById(pictureReviewRequest.getId());
        ThrowUtils.throwIf(p.getReviewStatus().equals(ReviewStatus.PASSED.getCode()), StatusCode.BAD_REQUEST, "图片已审核通过，无需重复审核");
        // 实例转换
        Picture picture = new Picture();
        BeanUtil.copyProperties(pictureReviewRequest, picture);
        picture.setReviewerId(loginUser.getId());
        picture.setReviewTime(new Date());
        // 执行审核操作
        this.updateById(picture);
    }

    @Override
    public PictureVO ObjToVO(Picture picture) {
        PictureVO pictureVO = new PictureVO();
        BeanUtil.copyProperties(picture,pictureVO);
        pictureVO.setTags(JSONUtil.toList(picture.getTags(), String.class));
        return pictureVO;
    }

    @Override
    public List<PictureVO> ObjToVO(List<Picture> pictures) {
        return pictures.stream().map(this::ObjToVO).collect(Collectors.toList());
    }

    @Override
    public List<Picture> randomPicturesWithCache(int number) {
        List<Picture> randomPictures;
        // 从caffeine本地缓存查询
        randomPictures = caffeineCache.getRandomPictures(number);
        if (randomPictures!=null){
            return randomPictures;
        }
        // 从redis缓存查询
        randomPictures = redisCache.getRandomPictures(number);
        if (randomPictures!=null){
            // 存入本地缓存
            caffeineCache.setRandomPictures(number,randomPictures);
            return randomPictures;
        }
        // 从数据库查询
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("space_id")
                .last("ORDER BY RAND() LIMIT " + number)
                .like("tags","精选");
        randomPictures = this.list(queryWrapper);
        // 存入缓存
        caffeineCache.setRandomPictures(number,randomPictures);
        redisCache.setRandomPictures(number,randomPictures);
        return randomPictures;
    }

    @Override
    public void deletePicturesBySpaceId(long spaceId, User loginUser) {
        // 检查空间是否存在(如果不存在会在其他方法抛异常)
        Space space = spaceService.getSpaceById(spaceId);
        // 管理员或者本人
        ThrowUtils.throwIf(!Authority.inManage(loginUser) && !loginUser.getId().equals(space.getUserId()),
                StatusCode.FORBIDDEN);
        // 查询所有数据
        List<Picture> pictures = this.lambdaQuery()
                .eq(Picture::getSpaceId, spaceId)
                .list();
        if (pictures.isEmpty()){
            return;
        }
        // 使用事务执行数据库删除操作
        transactionTemplate.execute(status -> {
            LambdaQueryWrapper<Picture> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Picture::getSpaceId, spaceId);
            this.remove(queryWrapper);
            return null;
        });
        // 依次删除对象存储中的图片
        try {
            for (Picture picture : pictures) {
                cosUtils.deletePictureByObject(picture);
            }
        } catch (Exception e) {
            // 人工介入恢复
            log.error("COS删除失败，需手动处理图片: {}", pictures);
        }
    }

    @Override
    public void clearPictureCache() {
        caffeineCache.clearPicture();
        redisCache.clearPicture();
    }

    /**
     * 构建入库数据
     */
    Picture buildPicture(PictureUploadResult pictureUploadResult, User loginUser, Long spaceId){
        Picture picture = new Picture();
        picture.setId(null);
        picture.setName(pictureUploadResult.getName());
        picture.setUrl(pictureUploadResult.getUrl());
        picture.setThumbnailUrl(pictureUploadResult.getThumbnailUrl());
        picture.setIntroduction(null);
        picture.setCategory(null);
        picture.setTags(null);
        picture.setPictureSize(pictureUploadResult.getPictureSize());
        picture.setPictureWidth(pictureUploadResult.getPictureWidth());
        picture.setPictureHeight(pictureUploadResult.getPictureHeight());
        picture.setPictureScale(pictureUploadResult.getPictureScale());
        picture.setPictureFormat(pictureUploadResult.getPictureFormat());
        picture.setUserId(loginUser.getId());
        picture.setSpaceId(spaceId);
        picture.setCreateTime(null);
        picture.setEditTime(new Date());
        picture.setUpdateTime(null);
        picture.setIsDelete(null);
        // 管理员上传的自动审核
        this.fillReviewInfo(picture,loginUser);
        return picture;
    }

    private void fillReviewInfo(Picture picture, User loginUser) {
        // 如果是管理员上传的图片，自动通过审核
        if (Authority.inManage(Role.getEnumByCode(loginUser.getRole()))){
            picture.setReviewerId(loginUser.getId());
            picture.setReviewStatus(ReviewStatus.PASSED.getCode());
            picture.setReviewMessage(String.format("此图片由管理员%1$d上传",loginUser.getId()));
            picture.setReviewTime(new Date());
        }else {
            // 不是管理员上传的就设置为待审核
            picture.setReviewStatus(ReviewStatus.PENDING.getCode());
            if (picture.getReviewerId()!=null && picture.getReviewTime()!=null){
                picture.setReviewMessage("用户修改了图片，需要重新审核");
            }
        }
    }

    /**
     * 校验图片文件
     */
    private void validPicture(Picture picture){
        final int MAX_URL_LENGTH = 1024;
        final int MAX_INTRODUCTION_LENGTH = 1000;
        ThrowUtils.throwIf(picture == null,StatusCode.BAD_REQUEST,"图片不可为空");
        ThrowUtils.throwIf(ObjUtil.isNull(picture.getId()), StatusCode.BAD_REQUEST, "ID不能为空");
        if (StrUtil.isNotBlank(picture.getUrl()))
            ThrowUtils.throwIf(picture.getUrl().length() > MAX_URL_LENGTH, StatusCode.BAD_REQUEST, "图片地址长度过长");
        if (StrUtil.isNotBlank(picture.getIntroduction()))
            ThrowUtils.throwIf(picture.getIntroduction().length() > MAX_INTRODUCTION_LENGTH, StatusCode.BAD_REQUEST, "图片简介长度过长");
    }
}
